var users = {};

// Keep a running auto-incrementer.
var primaryKey = 0;


// ---------------------------------------------------------- //
// ---------------------------------------------------------- //


// Now, we have to define the exteranl, public API of the module.
// Each of the methods in this API gets "exported" as part of the
// exposed object.


// All of these methods deal with data READS and WRITES. In Node,
// this kind of I/O is supposed to be asynchronous; that is, a
// method that reads or writes to storage can't return a value
// directly (as it is non-blocking... for the most part). Therefore,
// we have to pass callbacks to all of our IO methods so that our
// calling context can be *alerted* to data events.


// I am creating a noop function so I can simplify the logic
// surrounding my callbacks. With a noop() (read as No-Op), I can
// always have a reference to *a* callback.

//========require starts========
var $ = require;

var util = $('../utils/objectUtils'),
    fs = $('fs'),
    path = $('path'),
    nodeDBI = $('node-dbi'),
    dbconfig = $('../config').dbconfig,
    _ = $('underscore'),
    dbutil = $('../utils/dbWrapperUtil');


//========static variables========
var USER_TABLE = 'user';


//========local variable========
var DBWrapper = nodeDBI.DBWrapper;


//========functions========
var noop = function(){};

var isValidUser = function(user){
    return user && user.user_id
           && user.oauth_access_token
           && user.oauth_access_token_secret;
};

var add = exports.add = function( user, callback ){
    callback = (callback || noop);
    if(!isValidUser(user)){
        callback(null);
    }else{
        dbutil.dbtemplate(function(dbwrapper, dbcloseCallback){
            dbwrapper.insert(USER_TABLE, user, function(err, affectedRows){
                dbcloseCallback();
                if(!err){
                    console.log('add user ok');
                    callback(null, user);
                }else{
                    console.log('add user fail');
                    callback(err, user);
                }
            });
        });
    }
    // Return this object reference to allow for method chaining.
    return( this );
};


// I delete the user with the given ID.
var remove = exports.delete = function(user_id, callback ){
    //user object
    if(_.isObject(user_id)){
        user_id = user_id.user_id;
    }

    if (user_id){
        dbutil.dbtemplate(function(dbwrapper, dbCloseCallback){
                dbwrapper.remove(USER_TABLE, ['user_id=' + user_id], function(err, affectedRow){
                    dbCloseCallback();
                    callback(err, affectedRow);
                });
        });
    }else{
        callback(null, 0);
    }


    // Return this object reference to allow for method chaining.
    return( this );
};


// I return the user with the given id.
var get = exports.get = function(user_id, callback ){
    //user object
    if(_.isObject(user_id)){
        user_id = user_id.user_id;
    }

    if(user_id){
        dbutil.dbtemplate(function(dbwrapper, dbCloseCallback){
            //TODO: import extjs for nodejs
            //var sql = String.format('select * from {0} where user_id=?', USER_TABLE);
            var sql = 'select * from ' + USER_TABLE + ' where user_id=?';
            dbwrapper.fetchRow(sql, [user_id], function(err, result){
                dbCloseCallback();
                callback(err, result);
            });
        });
    }else{
        callback({message:'miss user_id'}, null);
    }
    return( this );
};


var getAll = exports.getAll = function( callback ){
    callback = (callback || noop);
    dbutil.dbtemplate(function(dbwrapper, closeCallback){
        dbwrapper.fetchAll('select * from ' + USER_TABLE, null, function(err, result){
            closeCallback();
            callback(err, result);
        });
    });
    return( this );
};

var upsert = exports.upsert = function(newuser, callback){
    var user_id = newuser.user_id;
    if(user_id){
        get(user_id, function(err, result){
            if(!err){
                if(result){
                    console.log(user_id + ' exists');
                    callback(null, result);
                }else{
                    console.log(user_id + ' does not exist, ready to add a new user');
                    add(newuser, callback);
                }
            }else{
                callback(err, []);
            }
        });
    }
    return this;
};
